package com.pine.service.pineframework.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.pine.common.beans.exception.BusinessException;
import com.pine.common.beans.exception.ExceptionCodeEnum;
import com.pine.common.beans.pineframework.request.SysDeptQueryRequest;
import com.pine.common.beans.pineframework.response.SysDeptQueryResponse;
import com.pine.common.beans.request.PageRequest;
import com.pine.common.beans.response.DropDownTreeResponse;
import com.pine.common.beans.response.PageResponse;
import com.pine.dao.pineframework.constants.StatusEnum;
import com.pine.dao.pineframework.entity.SysDept;
import com.pine.manager.pineframework.SysDeptManager;
import com.pine.manager.pineframework.bo.SysDeptBo;
import com.pine.manager.pineframework.convertors.SysDeptConvertor;
import com.pine.manager.pineframework.query.SysDeptQuery;
import com.pine.service.pineframework.SysDeptService;
import com.pine.service.util.PageUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 部门表 服务实现类
 * </p>
 *
 * @author pine manage
 * @since 2024-08-12
 */
@Slf4j
@Service
public class SysDeptServiceImpl implements SysDeptService {

    @Resource
    private SysDeptManager sysDeptManager;

    @Resource
    private SysDeptConvertor sysDeptConvertor;

    private static final Map<String, SFunction<SysDept, ?>> COLUMNS_FUNCTION_MAP;

    static {
        COLUMNS_FUNCTION_MAP = Map.of(
                "id", SysDept::getId
        );
    }


    /**
     * 通过唯一key查询单个数据
     *
     * @param uniqueKey 唯一键
     * @param column    列名
     * @return 单个数据查询响应结果
     */
    @Override
    public SysDeptQueryResponse getOneByUniqueKey(Object uniqueKey, String column) {
        // 根据业务ID查询
        SysDeptBo sysDeptBo = sysDeptManager.getOneByUniqueKey(uniqueKey, COLUMNS_FUNCTION_MAP.getOrDefault(column, SysDept::getId));
        return sysDeptConvertor.entityBoToQueryResponse(sysDeptBo);
    }

    /**
     * 查询信息（不分页）
     *
     * @param request 请求
     * @return 响应
     */
    @Override
    public List<SysDeptQueryResponse> list(SysDeptQueryRequest request) {
        SysDeptQuery sysDeptQuery = sysDeptConvertor.queryRequestToQuery(request);
        if (ObjectUtils.isNotEmpty(sysDeptQuery)) {
            List<SysDeptBo> sysDeptList = sysDeptManager.list(sysDeptQuery);
            if (ObjectUtils.isNotEmpty(sysDeptList)) {
                return sysDeptList.stream()
                        .map(sysDeptConvertor::entityBoToQueryResponse)
                        .filter(ObjectUtils::isNotEmpty)
                        .collect(Collectors.toList());
            }
        }
        return Collections.emptyList();
    }


    /**
     * 查询信息（分页）
     *
     * @param request 请求
     * @return PageResponse 响应
     */
    @Override
    public PageResponse<SysDeptQueryResponse> listPages(PageRequest<SysDeptQueryRequest> request) {
        try {
            // 分页查询
            IPage<SysDeptBo> sysDeptPage = sysDeptManager.page(transformToQuery(request));

            // 安全地处理分页转换逻辑
            return safelyConvertPage(sysDeptPage);
        } catch (Exception e) {
            log.error("查询失败", e);
            throw new BusinessException(ExceptionCodeEnum.SELECT_ERROR);
        }
    }


    /**
     * 安全地将分页数据转换为响应对象
     *
     * @param sysDeptPage 分页查询结果
     * @return 分页响应对象
     */
    private PageResponse<SysDeptQueryResponse> safelyConvertPage(IPage<SysDeptBo> sysDeptPage) {
        if (sysDeptPage == null || sysDeptPage.getRecords() == null) {
            return new PageResponse<>();
        }

        // 使用并行流进行转换以提高效率，但需确保线程安全
        List<SysDeptQueryResponse> responses = sysDeptPage.getRecords().parallelStream()
                .map(sysDeptBo -> sysDeptConvertor.entityBoToQueryResponse(sysDeptBo))
                .collect(Collectors.toList());

        return PageUtil.convertPage(sysDeptPage, responses);
    }


    /**
     * 将请求 request 转换成 manager 的 query 对象
     *
     * @param request 请求参数
     * @return query 对象
     */
    private PageRequest<SysDeptQuery> transformToQuery(PageRequest<SysDeptQueryRequest> request) {
        SysDeptQuery sysDeptQuery = sysDeptConvertor.queryRequestToQuery(request.getData());
        return new PageRequest<>(request.getPageNum(), request.getPageSize(), sysDeptQuery);
    }


    /**
     * 查询部门及子部门
     *
     * @param deptId 顶层部门ID
     * @return 部门列表
     */
    @Override
    public List<SysDept> listDeptAndChild(Long deptId) {
        // 递归查询部门和子部门
        return sysDeptManager.getMapper().listDeptAndChild(deptId);
    }

    /**
     * 下拉选择，查询部门树形结构
     *
     * @return 部门树形结构
     */
    @Override
    public List<DropDownTreeResponse<Long>> dropDownTree() {
        // 查询启用中的全部部门
        SysDeptQuery sysDeptQuery = new SysDeptQuery();
        sysDeptQuery.setStatus(StatusEnum.ENABLE);
        List<SysDeptBo> sysDeptList = sysDeptManager.list(sysDeptQuery);
        if (ObjectUtil.isEmpty(sysDeptList)) {
            return Collections.emptyList();
        }

        // 转换结构
        return sysDeptList.stream()
                .map(sysDept -> {
                    DropDownTreeResponse<Long> dropDownTreeResponse = new DropDownTreeResponse<>();
                    dropDownTreeResponse.setValue(sysDept.getId());
                    dropDownTreeResponse.setLabel(sysDept.getName());
                    dropDownTreeResponse.setParentId(sysDept.getParentId());
                    dropDownTreeResponse.setWeight(sysDept.getSort());
                    return dropDownTreeResponse;
                }).toList();
    }
}
